package com.lfs.dingtalk.robot.web;

import com.aliyun.dingtalkcard_1_0.models.*;
import com.aliyun.teautil.models.RuntimeOptions;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.request.OapiV2UserGetbymobileRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import com.dingtalk.api.response.OapiV2UserGetbymobileResponse;
import com.lfs.dingtalk.robot.domain.DingTalkSentRequest;
import com.lfs.dingtalk.robot.domain.GroupChatSendRequest;
import com.lfs.dingtalk.robot.servcie.DingTalkService;
import com.lfs.dingtalk.robot.servcie.MessageTypeStrategyContext;
import com.taobao.api.ApiException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.web.bind.annotation.*;
import com.aliyun.tea.*;
import shade.com.alibaba.fastjson2.JSON;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.UUID;
import com.aliyun.tea.*;
import com.aliyun.teautil.*;
import com.aliyun.teautil.models.*;
import com.aliyun.dingtalkrobot_1_0.*;
import com.aliyun.dingtalkrobot_1_0.models.*;
import com.aliyun.teaopenapi.models.*;
import com.aliyun.dingtalkcard_1_0.models.CreateCardHeaders;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;


import static com.lfs.dingtalk.robot.constants.CommonConstant.*;

@RequestMapping("/dingTalk")
@RestController
@Slf4j
public class DingTalkController {

    private final static String UNION_ID = "DiPiipdwiPcOpbKaaxHqbXKHQiEiE";
    private final static String username = "02500732495021689248";


    /**
     * 开放接口创建卡片实例
     */
    @GetMapping(value = "/instance")
    public void instance() throws Exception {
        com.aliyun.dingtalkcard_1_0.Client client = createClient();
        CreateCardHeaders createCardHeaders = new CreateCardHeaders();
        createCardHeaders.xAcsDingtalkAccessToken = DingTalkService.getAccessToken();

        PrivateDataValue privateDataValueKey = new PrivateDataValue();
        Map<String, PrivateDataValue> privateData = TeaConverter.buildMap(
                new TeaPair("privateDataValueKey", privateDataValueKey)
        );
        CreateCardRequest.CreateCardRequestCardData cardData = new CreateCardRequest.CreateCardRequestCardData();
        cardData.setCardParamMap(TeaConverter.buildMap(
                new TeaPair("title", "重要消息"),
                new TeaPair("content", "请在会议室集合"),
                new TeaPair("data", "biu biu biu")
        ));

        CreateCardRequest createCardRequest
                = new CreateCardRequest()
//                .setUserId()
                .setUserIdType(1)
                .setOutTrackId("lfs-1145141919810")
                .setCardTemplateId("db4112a8-9e49-46aa-91e4-0c9a2868fe75.schema")
//                .setPrivateData(privateData);
                .setCardData(cardData);
        try {
            CreateCardResponse cardWithOptions = client.createCardWithOptions(createCardRequest, createCardHeaders, new RuntimeOptions());
            log.info("卡片创建结果：{}", JSON.toJSONString(cardWithOptions));
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !Common.empty(err.message)) {
                err.printStackTrace();
                log.error(err.code);
                log.error(err.message);
            }
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!Common.empty(err.code) && !Common.empty(err.message)) {
                _err.printStackTrace();
                log.error(err.code);
                log.error(err.message);
            }
        }
    }



    /**
     * 使用 Token 初始化账号Client
     *
     * @return Client
     * @throws Exception
     */
    public static com.aliyun.dingtalkcard_1_0.Client createClient() throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkcard_1_0.Client(config);
    }


    @GetMapping(value = "/send")
    public void call() throws Exception{
        String accessToken = DingTalkService.getAccessToken();
        com.aliyun.dingtalkcard_1_0.Client client = createClient();
        com.aliyun.dingtalkcard_1_0.models.CreateAndDeliverHeaders createAndDeliverHeaders = new com.aliyun.dingtalkcard_1_0.models.CreateAndDeliverHeaders();
        createAndDeliverHeaders.xAcsDingtalkAccessToken = accessToken;
        com.aliyun.dingtalkcard_1_0.models.CreateAndDeliverRequest createAndDeliverRequest = new com.aliyun.dingtalkcard_1_0.models.CreateAndDeliverRequest()
                .setUserId("example_user_id")
                .setCardTemplateId("e3eedd7e-e6cd-455e-8c86-1d08ec1dc5d2.schema")
                .setOutTrackId("lfs"+UUID.randomUUID())
                .setCallbackType("STREAM")
//                .setCallbackRouteKey("example_route_key")
                .setCardData(new com.aliyun.dingtalkcard_1_0.models.CreateAndDeliverRequest.CreateAndDeliverRequestCardData()
                        .setCardParamMap(TeaConverter.buildMap(
                                new TeaPair("title", "周报查看!!"),
                                new TeaPair("content", "请在电脑上查看本周的周报信息!!"),
                                new TeaPair("phoneAddress", "https://www.dingtalk.com/"),
                                new TeaPair("pcAddress", "https://www.google.com.hk")
                        )))
//                .setPrivateData(privateData)  //用户私有数据
//                .setOpenDynamicDataConfig(openDynamicDataConfig) //动态数据源配置
                .setImRobotOpenSpaceModel(new com.aliyun.dingtalkcard_1_0.models.CreateAndDeliverRequest.CreateAndDeliverRequestImRobotOpenSpaceModel()
                        .setSupportForward(true)
//                        .setLastMessageI18n(TeaConverter.buildMap(
//                                new TeaPair("key", "互动卡片消息")
//                        ))
//                        .setSearchSupport(new com.aliyun.dingtalkcard_1_0.models.CreateAndDeliverRequest.CreateAndDeliverRequestImRobotOpenSpaceModelSearchSupport()
//                                .setSearchIcon("@lALPDgQ9q8hFhlHNAXzNAqI")
//                                .setSearchTypeName("{\"zh_CN\":\"待办\",\"zh_TW\":\"待辦\",\"en_US\":\"ToDo\"}")
//                                .setSearchDesc("卡片的具体描述"))
                        .setNotification(new com.aliyun.dingtalkcard_1_0.models.CreateAndDeliverRequest.CreateAndDeliverRequestImRobotOpenSpaceModelNotification()
                                .setAlertContent("你收到了1条神秘消息")
                                .setNotificationOff(false)))
                .setOpenSpaceId("dtv1.card//IM_ROBOT."+UNION_ID)
                .setCallbackType("STREAM")
                .setImRobotOpenDeliverModel(new com.aliyun.dingtalkcard_1_0.models.CreateAndDeliverRequest.CreateAndDeliverRequestImRobotOpenDeliverModel()
                        .setSpaceType("IM_ROBOT")
                        .setRobotCode(ROBOT_CODE)
//                        .setExtension(TeaConverter.buildMap(
//                                new TeaPair("title", "周报查看!!"),
//                                new TeaPair("content", "请在电脑上查看本周的周报信息!!"),
//                                new TeaPair("phoneAddress", "https://dingding-erdp.seres.cn"),
//                                new TeaPair("pcAddress", "https://www.baidu.com")
//                        ))
                )
                .setUserIdType(2);  //1（默认）：userId模式 2 unionId模式
        try {
            CreateAndDeliverResponse response = client.createAndDeliverWithOptions(createAndDeliverRequest, createAndDeliverHeaders, new RuntimeOptions());
            log.info("请求结果：{}",JSON.toJSONString(response.getBody()));
            log.info("outTrackId:{}",response.getBody().getResult().getOutTrackId());
            log.info("deliverResults:{}",JSON.toJSONString(response.getBody().getResult().getDeliverResults()));
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                log.error("错误码：{}",err.getCode());
                log.error("错误信息：{}",err.getMessage());
                err.printStackTrace();
            }
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                log.error("错误码：{}",err.getCode());
                log.error("错误信息：{}",err.getMessage());
                err.printStackTrace();
            }

        }
    }



    @PostMapping(value = "/withdraw")
    public void dingTalkWithdraw(DingTalkSentRequest request) throws Exception {
        String accessToken = DingTalkService.getAccessToken();
        com.aliyun.dingtalkrobot_1_0.Client client = new com.aliyun.dingtalkrobot_1_0.Client(new Config(){{
            protocol = "https";
            regionId = "central";
        }});
        BatchRecallOTOHeaders batchRecallOTOHeaders = new BatchRecallOTOHeaders();
        batchRecallOTOHeaders.xAcsDingtalkAccessToken = accessToken;
        BatchRecallOTORequest batchRecallOTORequest = new BatchRecallOTORequest()
                .setRobotCode(APP_KEY)  //普通机器人code和appId是同一个
                .setProcessQueryKeys(request.getProcessQueryKeys());
        try {
            client.batchRecallOTOWithOptions(batchRecallOTORequest, batchRecallOTOHeaders, new RuntimeOptions());
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                err.printStackTrace();
            }
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                err.printStackTrace();
            }

        }
    }


    @PostMapping(value = "/sendToUsers")
    public void dingTalkSendToUsers() throws Exception {
        String accessToken = DingTalkService.getAccessToken();
        com.aliyun.dingtalkrobot_1_0.Client client = new com.aliyun.dingtalkrobot_1_0.Client(new Config(){{
            protocol = "https";
            regionId = "central";
        }});
        BatchSendOTOHeaders batchSendOTOHeaders = new BatchSendOTOHeaders();
        batchSendOTOHeaders.xAcsDingtalkAccessToken = accessToken;
        BatchSendOTORequest batchSendOTORequest = new BatchSendOTORequest()
                .setRobotCode(APP_KEY)
                .setUserIds(Collections.singletonList(
                        "DiPiipdwiPcOpbKaaxHqbXKHQiEiE"
                ))
                .setMsgKey("sampleMarkdown")
                .setMsgParam("{\"text\": \"hello text\",\"title\": \"hello title\"}");
        try {
            client.batchSendOTOWithOptions(batchSendOTORequest, batchSendOTOHeaders, new RuntimeOptions());
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                err.printStackTrace();
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                err.printStackTrace();
            }

        }
    }

    /**
     * 自定义机器人发送
     * @param request
     * @return
     */
    @PostMapping(value = "/sendToGroup")
    public String groupChatSend(@RequestBody GroupChatSendRequest request) {
        String result = "fail";
        long timestamp = System.currentTimeMillis();
        try {
            String sign = getSign(request.getSecret(), timestamp);
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/robot/send"+"?sign="+sign+"&timestamp="+timestamp);
            OapiRobotSendRequest req = new OapiRobotSendRequest();
            GroupChatSendRequest.Type messageType = request.getMessageType();
            MessageTypeStrategyContext.getStrategy(messageType).prepareMessage(req, messageType);
            OapiRobotSendResponse rsp = client.execute(req, request.getWebhook().replace("https://oapi.dingtalk.com/robot/send?access_token=", ""));
            log.info("消息发送结果：{}", JSON.toJSONString(rsp.getBody()));
            if (rsp.getErrcode() == 0 ) result = "success";
            log.info("消息发送情况：{}", result);
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 平台机器人发送
     * @param request
     * @return
     */
    @PostMapping(value = "/sendGroup")
    public String sendGroup(@RequestBody GroupChatSendRequest request) {
        String result = "fail";
        long timestamp = System.currentTimeMillis();
        try {
            String sign = getSign(request.getSecret(), timestamp);
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/robot/send"+"?sign="+sign+"&timestamp="+timestamp);
            OapiRobotSendRequest req = new OapiRobotSendRequest();
            GroupChatSendRequest.Type messageType = request.getMessageType();
            MessageTypeStrategyContext.getStrategy(messageType).prepareMessage(req, messageType);
            OapiRobotSendResponse rsp = client.execute(req, request.getWebhook().replace("https://oapi.dingtalk.com/robot/send?access_token=", ""));
            log.info("消息发送结果：{}", JSON.toJSONString(rsp.getBody()));
            if (rsp.getErrcode() == 0 ) result = "success";
            log.info("消息发送情况：{}", result);
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return result;
    }




    @SneakyThrows
    public static String getSign(String secret,Long timestamp) {
        String stringToSign = timestamp + "\n" + secret;
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
        return URLEncoder.encode(new String(Base64.encodeBase64(signData)), String.valueOf(StandardCharsets.UTF_8));
    }


    @GetMapping(value = "/getByMobile/{mobile}")
    public OapiV2UserGetbymobileResponse getByMobile(@PathVariable String mobile){
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
            OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
            req.setMobile(mobile);
            OapiV2UserGetbymobileResponse rsp = client.execute(req, DingTalkService.getAccessToken());
            return rsp;
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return null;
    }
}
